unit LangFrm;

(* ======================================================== *)
(* TLangForm                                                *)
(* ======================================================== *)
(*   use this module with TLangMgr, support multi language  *)
(* form object for your application.                        *)
(*   tony                                                   *)
(*   2003.03.17                                             *)
(* ======================================================== *)

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  IniFiles, TypInfo, LangMgr;

type
  TLangForm = class (TForm, ILangIntf)
  private
    AIniFile:TIniFile;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
    procedure TranslateControls();
  protected
    procedure DoChangeLanguage(); virtual;
    function Translate(Ident:String;Default:String):String; overload;
    function Translate(Ident:String;Default:String;const Args:array of const):String; overload;
  public
    constructor Create(AOwner:TComponent); override;
    destructor Destroy(); override;
    function QueryInterface(const IID: TGUID; out Obj): HResult; override; stdcall;
    procedure GetLanguageList(LangList:TStringList;var LangIndex:Integer);
    procedure ChangeLanguage(LangIndex:Integer);
  end;

implementation

{ TLangForm }

//no use
//2003.03.17
function TLangForm.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  Result:=inherited QueryInterface(IID,obj);
end;

//no use
//2003.03.17
function TLangForm._AddRef: Integer;
begin
  Result:=inherited _AddRef;
end;

//no use
//2003.03.17
function TLangForm._Release: Integer;
begin
  Result:=inherited _Release;
end;

//translate all controls on the form
//2003.03.17
procedure TLangForm.TranslateControls();
const
  PropertyNames: array[0..2] of PChar = ('Caption', 'Text', 'Hint');
var
  Comp:TComponent;
  CompIndex,PropIndex:Integer;
  PropInfoPtr: PPropInfo;
  PropOldValue,PropNewValue:String;
begin
  Font.Charset:=AIniFile.ReadInteger('General','Charset',Font.Charset);
  Font.Name:=AIniFile.ReadString('General','FontName',Font.Name);
  Font.Size:=AIniFile.ReadInteger('General','FontSize',Font.Size);
  Caption:=Translate('Caption',Caption);
  for CompIndex:=0 to ComponentCount-1 do begin
    Comp:=Components[CompIndex];
    //translate the component
    for PropIndex:=Low(PropertyNames) to High(PropertyNames) do begin
      PropInfoPtr:=GetPropInfo(Comp,PropertyNames[PropIndex]);
      if PropInfoPtr=nil then continue;
      if PropInfoPtr^.PropType^.Kind=tklString then begin
        PropOldValue:=GetStrProp(Comp,PropInfoPtr);
        if (PropOldValue<>'-') then begin
          PropNewValue:=Translate(Comp.Name+'.'+PropertyNames[PropIndex],PropOldValue);
          SetStrProp(Comp,PropertyNames[PropIndex],PropNewValue);
        end;
      end;
    end;//for PropIndex
  end;//for CompIndex
end;

//change ini file
//2003.03.17
procedure TLangForm.DoChangeLanguage();
var
  FileName:String;
begin
  if Assigned(AIniFile) then begin
    FreeAndNil(AIniFile);
  end;
  FileName:=ALangMgr.GetActiveLangFileName();
  if FileExists(FileName) then begin
    AIniFile:=TIniFile.Create(FileName);
    try
      LockWindowUpdate(Handle);
      TranslateControls();
    finally
      LockWindowUpdate(0);
    end;
  end;
end;

//translate string
//2003.03.17
function TLangForm.Translate(Ident:String;Default:String):String;
begin
  Result:=Default;
  try
    if Assigned(AIniFile) then begin
      Result:=AIniFile.ReadString(ClassName,Ident,Default);
    end;
  except
  end;
end;

//translate string with format
//2003.03.17
function TLangForm.Translate(Ident:String;Default:String;const Args:array of const):String;
var
  StrTmp:String;
begin
  try
    StrTmp:=Translate(Ident,Default);
    Result:=Format(StrTmp,Args);
  except
    Result:=StrTmp;
  end;
end;

//constructor
//2003.03.17
constructor TLangForm.Create(AOwner:TComponent);
begin
  inherited Create(AOwner);
  ALangMgr.AddLangObj(self);
  DoChangeLanguage();
end;

//destructor
//2003.03.17
destructor TLangForm.Destroy();
begin
  AlangMgr.RemoveLangObj(self);
  AIniFile.Free;
  inherited Destroy();
end;

//call the language manager to get language list and active language's index
//2003.03.18
procedure TLangForm.GetLanguageList(LangList:TStringList;var LangIndex:Integer);
begin
  ALangMgr.GetLanguageList(LangList,LangIndex);
end;

//call the laguage manager to change the language
//2003.03.18
procedure TLangForm.ChangeLanguage(LangIndex:Integer);
begin
  ALangMgr.ChangeLanguage(LangIndex);
end;

end.
